<?php

namespace backend\models;


use yii\base\InvalidParamException;
use yii\base\Model;
use Yii;
use yii\helpers\Inflector;

class SettingForm extends Model
{
    /**
     * 设置标题
     *
     * @var string
     */
    private $_title;

    /**
     * 设置选项
     *
     * @var array
     */
    private $_options = [];

    /**
     * 设置分类
     *
     * @var string
     */
    private $_category = 'general';

    /**
     * @param string $category 分类
     * @param array $config
     * @throws \yii\base\InvalidParamException
     */
    public function __construct($category = 'general', $config = [])
    {
        if ($category) {
            $this->_category = $category;
        }

        $params = Yii::$app->params;
        if (isset($params['settings'][$this->_category])) {
            $settings = $params['settings'][$this->_category];
        } else {
            throw new InvalidParamException('设置分类未找到。');
        }

        if (isset($settings['title'])) {
            $this->_title = $settings['title'];
        } else {
            $this->_title = Inflector::camel2words($this->_category);
        }

        if (isset($settings['options'])) {
            $this->_options = $settings['options'];
        }

        /** @var \common\components\Option $option */
        $option = Yii::$app->get('option');
        foreach ($this->_options as $name => $params) {
            $optionName = $this->_category . '.' . $name;
            $this->_options[$name]['value'] = $option->get($optionName,
                isset($this->_options[$name]['default']) ? $this->_options[$name]['default'] : null);
        }

        parent::__construct($config);
    }

    /**
     * @inheritDoc
     */
    public function __get($name)
    {
        if (isset($this->_options[$name])) {
            if (isset($this->_options[$name]['value'])) {
                return $this->_options[$name]['value'];
            } else {
                return null;
            }
        } else {
            return parent::__get($name);
        }
    }

    /**
     * @inheritDoc
     */
    public function __set($name, $value)
    {
        if (isset($this->_options[$name])) {
            $this->_options[$name]['value'] = $value;
        } else {
            parent::__set($name, $value);
        }
    }

    /**
     * @inheritDoc
     */
    public function __unset($name)
    {
        if (isset($this->_options[$name])) {
            unset($this->_options[$name]['value']);
        } else {
            parent::__unset($name);
        }
    }

    /**
     * 获取设置的选项 用于表单渲染
     *
     * @return array
     */
    public function getOptions()
    {
        return $this->_options;
    }

    /**
     * @return string
     */
    public function getCategory()
    {
        return $this->_category;
    }

    /**
     * @return string
     */
    public function getTitle()
    {
        return $this->_title;
    }

    /**
     * 获取设置选项字段标签
     *
     * @return string
     */
    public function attributeLabels()
    {
        $labels = [];
        foreach ($this->_options as $name => $params) {
            $labels[$name] = isset($params['label']) ? $params['label'] : $name;
        }
        return $labels;
    }

    /**
     * 获取设置选项的字段规则
     *
     * @return array
     */
    public function rules()
    {
        $rules = array();
        $required = array();
        $typeRuleMap = array(
            'text' => 'string',
            'url' => 'url',
            'date' => 'date',
            'email' => 'email',
            'file' => 'file',
            'number' => 'number',
            'integer' => 'integer',
            'textarea' => 'safe',
            'html' => 'filter',
            'select' => 'in',
            'radio' => 'in',
            'checkbox' => 'in',
            'boolean' => 'boolean',
            'bool' => 'boolean',
            'image' => 'image',
            'captcha' => 'captcha',
            'match' => 'match',
        );

        foreach ($this->_options as $name => $params) {
            $type = isset($params['type']) ? $params['type'] : 'text';

            if (isset($params['require'])) {
                $required[] = $name;
            }

            if (!isset($params['rule'])) {
                $rule = isset($typeRuleMap[$type]) ? $typeRuleMap[$type] : 'string';
            } else {
                $rule = $params['rule'];
            }

            if (($name === 'bool' || $name === 'boolean') && !isset($params['data'])) {
                $params['data'] = ['0' => '否', '1' => '是'];
            }

            if (is_array($rule)) {
                foreach ($rule as $r => $options) {
                    $rules[] = array_merge([$name, $r], $options);
                }
            } else {
                $ruleOptions = isset($params['ruleOptions']) ? (array)$params['ruleOptions'] : [];
                if ($type === 'html') {
                    $ruleOptions['filter'] = ['yii\helpers\HtmlPurifier', 'process'];
                }

                if ($rule === 'in') {
                    $ruleOptions['range'] = isset($params['data']) ? array_keys((array)$params['data']) : array();
                }
                $rules[] = array_merge([$name, $rule], $ruleOptions);
            }
        }

        if ($required) {
            array_unshift($rules, [$required, 'required']);
        }

        return $rules;
    }

    /**
     * 保存设置
     *
     * @return boolean
     */
    public function save()
    {
        if (!isset($this->category) || !$this->validate()) {
            return false;
        }

        /** @var \common\components\Option $option */
        $option = Yii::$app->get('option');
        foreach ($this->_options as $name => $params) {
            $option->set($this->category . '.' . $name, $params['value'], false);
        }

        $option->deleteCache();
        return true;
    }
}